
#include "ImageUtils.h"

bool SmoothImage(BImage* image, float factor)
{
	int fmtlen = image->fmtlen();
	BByteArray* pixels = image->pixels();
	if (fmtlen > 0 && pixels && pixels->size())
	{
		BByteArray bytes = *pixels;
		BByte* ptrs[9];
		float fact = 1.0f / sqrtf(2.0f);
		float mult = 1.0f / (fact * 4.0f + 4.0f + factor);
		int width = image->width();
		int height = image->height();
		for (int row = 0; row < height; row++)
		{
			int prev = fmtlen * width * (row - 1);
			BByte* prevData = bytes.data() + prev;
			int curr = fmtlen * width * row;
			BByte* currData = bytes.data() + curr;
			int next = fmtlen * width * (row + 1);
			BByte* nextData = bytes.data() + next;
			for (int col = 0; col < width; col++)
			{
				int offset = fmtlen * col;
				BByte* ptr = pixels->data() + curr + offset;
				if (row > 0)
				{
					ptrs[0] = prevData + offset - fmtlen;
					ptrs[1] = prevData + offset;
					ptrs[2] = prevData + offset + fmtlen;
				}
				else
				{
					ptrs[0] = 0;
					ptrs[1] = 0;
					ptrs[2] = 0;
				}
				if (col > 0)
					ptrs[3] = currData + offset - fmtlen;
				else
					ptrs[3] = 0;
				ptrs[4] = currData + offset;
				if (col < width - 1)
					ptrs[5] = currData + offset + fmtlen;
				else
					ptrs[5] = 0;
				if (row < height - 1)
				{
					ptrs[6] = nextData + offset - fmtlen;
					ptrs[7] = nextData + offset;
					ptrs[8] = nextData + offset + fmtlen;
				}
				else
				{
					ptrs[6] = 0;
					ptrs[7] = 0;
					ptrs[8] = 0;
				}
				for (int i = 0; i < fmtlen; i++)
				{
					float v = 0;
					if (ptrs[0]) { v += *ptrs[0] * fact;	ptrs[0]++; }
					if (ptrs[1]) { v += *ptrs[1];			ptrs[1]++; }
					if (ptrs[2]) { v += *ptrs[2] * fact;	ptrs[2]++; }
					if (ptrs[3]) { v += *ptrs[3];			ptrs[3]++; }
					if (ptrs[4]) { v += *ptrs[4] * factor;	ptrs[4]++; }
					if (ptrs[5]) { v += *ptrs[5];		  	ptrs[5]++; }
					if (ptrs[6]) { v += *ptrs[6] * fact;  	ptrs[6]++; }
					if (ptrs[7]) { v += *ptrs[7];		  	ptrs[7]++; }
					if (ptrs[8]) { v += *ptrs[8] * fact;  	ptrs[8]++; }
					*ptr = (BByte)(v * mult);
					ptr++;
				}
			}
		}
		return true;
	}
	return false;
}
